/*
 * Copyright [2022] [https://www.xiaonuo.vip]
 *
 * Snowy采用APACHE LICENSE 2.0开源协议，您在使用过程中，需要注意以下几点：
 *
 * 1.请不要删除和修改根目录下的LICENSE文件。
 * 2.请不要删除和修改Snowy源码头部的版权声明。
 * 3.本项目代码可免费商业使用，商业使用请保留源码和相关描述文件的项目出处，作者声明等。
 * 4.分发源码时候，请注明软件出处 https://www.xiaonuo.vip
 * 5.不可二次分发开源参与同类竞品，如有想法可联系团队xiaonuobase@qq.com商议合作。
 * 6.若您的项目无法满足以上几点，需要更多功能代码，获取Snowy商业授权许可，请在官网购买授权，地址为 https://www.xiaonuo.vip
 */
package vip.xiaonuo.biz.modular.eduimg.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.CollStreamUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.noear.folkmq.client.MqClient;
import org.noear.folkmq.client.MqMessage;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import vip.xiaonuo.biz.core.enums.MQTopic;
import vip.xiaonuo.biz.modular.eduimggroup.entity.EduImgGroup;
import vip.xiaonuo.biz.modular.eduimggroup.mapper.EduImgGroupMapper;
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.page.CommonPageRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import vip.xiaonuo.biz.modular.eduimg.entity.EduImg;
import vip.xiaonuo.biz.modular.eduimg.mapper.EduImgMapper;
import vip.xiaonuo.biz.modular.eduimg.param.EduImgAddParam;
import vip.xiaonuo.biz.modular.eduimg.param.EduImgEditParam;
import vip.xiaonuo.biz.modular.eduimg.param.EduImgIdParam;
import vip.xiaonuo.biz.modular.eduimg.param.EduImgPageParam;
import vip.xiaonuo.biz.modular.eduimg.service.EduImgService;

import vip.xiaonuo.common.util.CommonDownloadUtil;
import vip.xiaonuo.common.util.CommonResponseUtil;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 图片库Service接口实现类
 *
 * @author 周弘杰
 * @date  2025/06/29 12:19
 **/
@Service
public class EduImgServiceImpl extends ServiceImpl<EduImgMapper, EduImg> implements EduImgService {
    @Resource
    MqClient mqClient;
    @Resource
    EduImgMapper eduImgMapper;
    @Resource
    EduImgGroupMapper eduImgGroupMapper;

    @Override
    public Page<EduImg> page(EduImgPageParam eduImgPageParam) {
        QueryWrapper<EduImg> queryWrapper = new QueryWrapper<EduImg>().checkSqlInjection();
        if(ObjectUtil.isNotEmpty(eduImgPageParam.getName())) {
            queryWrapper.lambda().like(EduImg::getName, eduImgPageParam.getName());
        }

        if (StringUtils.isNotBlank(eduImgPageParam.getGroupId())) {
            EduImgGroup eduImgGroup = eduImgGroupMapper.selectById(eduImgPageParam.getGroupId());
            Assert.notNull(eduImgGroup,"此图片分组不存在");
            ArrayList<String> imgGroupPath = new ArrayList<>(eduImgGroup.getParentPath());
            imgGroupPath.add(eduImgGroup.getId());
            String groupFullPathStr =imgGroupPath.parallelStream().map(s -> "'" + s + "'").collect(Collectors.joining(","));
            queryWrapper.apply("img_group_path = ARRAY["+groupFullPathStr+"]::varchar[]");

        }
        queryWrapper.lambda().orderByDesc(EduImg::getSortCode).orderByDesc(EduImg::getUpdateTime);
        return this.page(CommonPageRequest.defaultPage(), queryWrapper);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add( List<EduImgAddParam> addParamList) {
        List<EduImg> eduImgList = addParamList.parallelStream()
                .map(eduImgAddParam -> {
                    EduImg bean = BeanUtil.toBean(eduImgAddParam, EduImg.class);
                    bean.setUpdateTime(new Date());
                    return bean;
                }).toList();
        saveBatch(eduImgList);

        List<String> groupIds = Arrays.asList(addParamList.get(0).getImgGroupPath().get(addParamList.get(0).getImgGroupPath().size() - 1));
        try {
            mqClient.publish(MQTopic.IMAGE_GROUP_COUNT, new MqMessage(JSON.toJSONString(groupIds)));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(EduImgEditParam eduImgEditParam) {
        EduImg eduImg = this.queryEntity(eduImgEditParam.getId());
        List<String> beforeGroupIds = Arrays.asList(eduImg.getImgGroupPath().get(eduImg.getImgGroupPath().size() - 1));
        List<String> groupIds = Arrays.asList(eduImgEditParam.getImgGroupPath().get(eduImgEditParam.getImgGroupPath().size() - 1));

        BeanUtil.copyProperties(eduImgEditParam, eduImg);
        this.updateById(eduImg);

        try {
            mqClient.publish(MQTopic.IMAGE_GROUP_COUNT, new MqMessage(JSON.toJSONString(groupIds)));
            mqClient.publish(MQTopic.IMAGE_GROUP_COUNT, new MqMessage(JSON.toJSONString(beforeGroupIds)));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<EduImgIdParam> eduImgIdParamList) {
        // 执行删除
        List<String> list = CollStreamUtil.toList(eduImgIdParamList, EduImgIdParam::getId);
        List<EduImg> eduImgs = eduImgMapper.selectBatchIds(list);
        List<String> groupIds = eduImgs.parallelStream().map(eduImg -> eduImg.getImgGroupPath().get(eduImg.getImgGroupPath().size() - 1)).toList();

        this.removeByIds(list);
        try {
            mqClient.publish(MQTopic.IMAGE_GROUP_COUNT, new MqMessage(JSON.toJSONString(groupIds)));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public EduImg detail(EduImgIdParam eduImgIdParam) {
        return this.queryEntity(eduImgIdParam.getId());
    }

    @Override
    public EduImg queryEntity(String id) {
        EduImg eduImg = this.getById(id);
        if(ObjectUtil.isEmpty(eduImg)) {
            throw new CommonException("图片库不存在，id值为：{}", id);
        }
        return eduImg;
    }

    @Override
    public void downloadImportTemplate(HttpServletResponse response) throws IOException {
       File tempFile = null;
       try {
         List<EduImgEditParam> dataList = CollectionUtil.newArrayList();
         String fileName = "图片库导入模板_" + DateUtil.format(DateTime.now(), DatePattern.PURE_DATETIME_PATTERN) + ".xlsx";
         tempFile = FileUtil.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
         EasyExcel.write(tempFile.getPath(), EduImgEditParam.class).sheet("图片库").doWrite(dataList);
         CommonDownloadUtil.download(tempFile, response);
       } catch (Exception e) {
         log.error(">>> 图片库导入模板下载失败：", e);
         CommonResponseUtil.renderError(response, "图片库导入模板下载失败");
       } finally {
         FileUtil.del(tempFile);
       }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public JSONObject importData(MultipartFile file) {
        try {
            int successCount = 0;
            int errorCount = 0;
            JSONArray errorDetail = JSONUtil.createArray();
            // 创建临时文件
            File tempFile = FileUtil.writeBytes(file.getBytes(), FileUtil.file(FileUtil.getTmpDir() +
                    FileUtil.FILE_SEPARATOR + "eduImgImportTemplate.xlsx"));
            // 读取excel
            List<EduImgEditParam> eduImgEditParamList =  EasyExcel.read(tempFile).head(EduImgEditParam.class).sheet()
                    .headRowNumber(1).doReadSync();
            List<EduImg> allDataList = this.list();
            for (int i = 0; i < eduImgEditParamList.size(); i++) {
                JSONObject jsonObject = this.doImport(allDataList, eduImgEditParamList.get(i), i);
                if(jsonObject.getBool("success")) {
                    successCount += 1;
                } else {
                    errorCount += 1;
                    errorDetail.add(jsonObject);
                }
            }
            return JSONUtil.createObj()
                    .set("totalCount", eduImgEditParamList.size())
                    .set("successCount", successCount)
                    .set("errorCount", errorCount)
                    .set("errorDetail", errorDetail);
        } catch (Exception e) {
            log.error(">>> 图片库导入失败：", e);
            throw new CommonException("图片库导入失败");
        }
    }

    public JSONObject doImport(List<EduImg> allDataList, EduImgEditParam eduImgEditParam, int i) {
        String id = eduImgEditParam.getId();
        if(ObjectUtil.hasEmpty(id)) {
            return JSONUtil.createObj().set("index", i + 1).set("success", false).set("msg", "必填字段存在空值");
        } else {
            try {
                int index = CollStreamUtil.toList(allDataList, EduImg::getId).indexOf(eduImgEditParam.getId());
                EduImg eduImg;
                boolean isAdd = false;
                if(index == -1) {
                    isAdd = true;
                    eduImg = new EduImg();
                } else {
                    eduImg = allDataList.get(index);
                }
                BeanUtil.copyProperties(eduImgEditParam, eduImg);
                if(isAdd) {
                    allDataList.add(eduImg);
                } else {
                    allDataList.remove(index);
                    allDataList.add(index, eduImg);
                }
                this.saveOrUpdate(eduImg);
                return JSONUtil.createObj().set("success", true);
            } catch (Exception e) {
              log.error(">>> 数据导入异常：", e);
              return JSONUtil.createObj().set("success", false).set("index", i + 1).set("msg", "数据导入异常");
            }
        }
    }


    @Override
    public void exportData(List<EduImgIdParam> eduImgIdParamList, HttpServletResponse response) throws IOException {
       File tempFile = null;
       try {
         List<EduImgEditParam> dataList;
         if(ObjectUtil.isNotEmpty(eduImgIdParamList)) {
            List<String> idList = CollStreamUtil.toList(eduImgIdParamList, EduImgIdParam::getId);
            dataList = BeanUtil.copyToList(this.listByIds(idList), EduImgEditParam.class);
         } else {
            dataList = BeanUtil.copyToList(this.list(), EduImgEditParam.class);
         }
         String fileName = "图片库_" + DateUtil.format(DateTime.now(), DatePattern.PURE_DATETIME_PATTERN) + ".xlsx";
         tempFile = FileUtil.file(FileUtil.getTmpDir() + FileUtil.FILE_SEPARATOR + fileName);
         EasyExcel.write(tempFile.getPath(), EduImgEditParam.class).sheet("图片库").doWrite(dataList);
         CommonDownloadUtil.download(tempFile, response);
       } catch (Exception e) {
         log.error(">>> 图片库导出失败：", e);
         CommonResponseUtil.renderError(response, "图片库导出失败");
       } finally {
         FileUtil.del(tempFile);
       }
    }
}
